import { getUid } from 'ol/util'
import { OlVectorLayer } from './type'
import VectorSource from 'ol/source/Vector'
import TrackAnimation from './TrackAnimation'

class WVectorLayer {
	constructor({ map, className = 'ol-layer', features = [], style = { zIndex: 9 } }) {
		this.WTYPE = 'VECTORLAYER'
		this.map = map
		// 默认的矢量图层
		this.olTarget = createVectorLayer(className, features, style)
		this.id = getUid(this.olTarget)
		// 存储事件
		this.WEvents = new Map()
		this.animationEvents = new Map()
		// 初始化
		this.init()
	}
	init() {
		const vectorLayer = this.olTarget
		this.getSource = vectorLayer.getSource.bind(vectorLayer)
		this.getZIndex = vectorLayer.getZIndex.bind(vectorLayer)
		this.getVisible = vectorLayer.getVisible.bind(vectorLayer)
		this.setSource = vectorLayer.setSource.bind(vectorLayer)
		this.setZIndex = vectorLayer.setZIndex.bind(vectorLayer)
		this.setVisible = vectorLayer.setVisible.bind(vectorLayer)
		this.setStyle = vectorLayer.setStyle.bind(vectorLayer)
		this.dispatchEvent = vectorLayer.dispatchEvent.bind(vectorLayer)
		this.on = vectorLayer.on.bind(vectorLayer)
		this.un = vectorLayer.un.bind(vectorLayer)
		this.addFeature = feature => this.getSource().addFeature(feature)
		this.addFeatures = features => this.getSource().addFeatures(features)
		this.removeFeature = feature => this.getSource().removeFeature(feature)
		this.hasFeature = feature => this.getSource().hasFeature(feature)
		this.getFeatures = () => this.getSource().getFeatures()
		this.getFeatureById = id => this.getSource().getFeatureById(id)
		this.getFeaturesAtCoordinate = coordinate => this.getSource().getFeaturesAtCoordinate(coordinate)
		this.forEachFeature = callBack => this.getSource().forEachFeature(feature => callBack(feature))
		this.getId = () => this.id
		// 清空图层矢量 feature
		this.clear = () => {
			this.getSource().clear()
			return this
		}
		// 添加 单个或者多个  feature
		this.add = (...args) => {
			if (args.length === 1) {
				const target = args[0]
				const WTYPE = target.WTYPE ? target.WTYPE : 'unknown'
				const targetSwitch = {
					FEATUREMARKER: () => {
						this.getSource().addFeature(target.olTarget)
					},
					// 点 矢量图
					Point: () => {
						this.getSource().addFeature(target.olTarget)
						target.olTarget.set('map', this.map)
						target.olTarget.set('source', this.getFeatures())
					},
					// 线 矢量图
					Line: () => {
						this.getSource().addFeature(target.olTarget)
						target.olTarget.set('map', this.map)
						target.olTarget.set('source', this.getFeatures())
					},
					// 圆形 矢量图
					Circle: () => {
						this.getSource().addFeature(target.olTarget)
						target.olTarget.set('map', this.map)
						target.olTarget.set('source', this.getFeatures())
					},
					// 多边形 矢量图
					Polygon: () => {
						this.getSource().addFeature(target.olTarget)
						target.olTarget.set('map', this.map)
						target.olTarget.set('source', this.getFeatures())
					},
					// 矩形 矢量图
					Rectangle: () => {
						this.getSource().addFeature(target.olTarget)
						target.olTarget.set('map', this.map)
						target.olTarget.set('source', this.getFeatures())
					},
					unknown: () => {}
				}
				Array.isArray(target) ? this.add(...target) : targetSwitch[WTYPE]()
			} else {
				args.forEach(marker => this.add(marker))
			}
			return this
		}
		// 删除单个或者多个  feature
		this.remove = (...args) => {
			if (args.length === 1) {
				// 单参数或者数组
				const target = args[0]
				if (!target) return target
				if (Array.isArray(target)) {
					target.forEach(marker => this.remove(marker))
				} else {
					const removeFeatureCallBack = (olTarget, callBack) => {
						const vectorLayerSource = this.getSource()
						if (vectorLayerSource.hasFeature(olTarget)) {
							vectorLayerSource.removeFeature(olTarget)
							callBack && callBack()
						}
					}
					const WTYPE = target.WTYPE ? target.WTYPE : null
					if (WTYPE) {
						const olTarget = target.olTarget ? target.olTarget : target
						removeFeatureCallBack(olTarget)
					}
				}
			} else {
				// 多个参数
				args.forEach(marker => this.remove(marker))
			}
			return this
		}
		//添加 moving 事件监听
		this.addeventlistener('moving')

		this.map.addLayer(vectorLayer)
	}
	//添加事件监听
	addeventlistener(type) {
		if (type === 'moving') {
			this.on(type, e => {
				const { type, eventName, moveCallBack, path, speed, lineFeature, marker, status, updateSpeed, updateDistance, circlable, angleFixed, virtualPath } = e
				// 是否存在 当前marker 动画
				const isExitMarkerMove = this.WEvents.has(eventName)
				const moveStatusHandler = {
					startMove: () => {
						//当前marker 已经存在动画
						if (isExitMarkerMove) {
							// 获取动画对象
							const animationObject = this.WEvents.get(eventName)
							// 已经停止时
							if (animationObject.status !== 'stopMove' && !animationObject.isArrived) {
								// 不需要再次触发停止-否则不会从新开始
								animationObject.stopMove()
							}
							//删除之前的动画
							this.WEvents.delete(eventName)
						}
						//初始化完整动画对象
						const animationObject = new TrackAnimation({
							vectorLayer: this,
							type,
							eventName,
							marker,
							speed,
							path,
							lineFeature,
							circlable,
							angleFixed,
							virtualPath
						})
						// 保存当前动画
						this.WEvents.set(eventName, animationObject)
						//初始化动画
						animationObject.initMove()
						//开始动画效果
						animationObject.startMove()
					},
					pauseMove: () => {
						if (isExitMarkerMove) {
							const animationObject = this.WEvents.get(eventName)
							if (animationObject.status === 'stopMove') return
							animationObject.stopMove(true)
						}
					},
					resumeMove: () => {
						if (isExitMarkerMove) {
							const animationObject = this.WEvents.get(eventName)
							if (animationObject.status === 'moving') return
							animationObject.resumeMove()
						}
					},
					stopMove: () => {
						if (isExitMarkerMove) {
							const animationObject = this.WEvents.get(eventName)
							animationObject.stopMove()
							this.WEvents.delete(eventName)
						}
					},
					updateSpeed: () => {
						if (isExitMarkerMove) {
							const animationObject = this.WEvents.get(eventName)
							animationObject.updateSpeed(Number(updateSpeed))
						}
					},
					updateDistance: () => {
						if (isExitMarkerMove) {
							const animationObject = this.WEvents.get(eventName)
							animationObject.updateDistance(Number(updateDistance))
						}
					},
					moveCallBack: () => {
						this.animationEvents.set(eventName, { moveCallBack })
						if (isExitMarkerMove) {
							const animationObject = this.WEvents.get(eventName)
							animationObject.updateMoveCallBack(moveCallBack)
						}
					}
				}
				moveStatusHandler[status]()
			})
		}
	}
}
//创建矢量标注图层
function createVectorLayer(className, features, style) {
	//矢量标注的数据源
	const vectorSource = new VectorSource({
		features
	})
	//矢量标注图层
	const vectorLayer = new OlVectorLayer({
		className,
		source: vectorSource,
		zIndex: style.zIndex
	})
	return vectorLayer
}

export default WVectorLayer
